package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageResponse;
import com.zzyl.base.ResponseResult;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.DeviceDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.enums.DeviceLocationTypeEnum;
import com.zzyl.enums.DevicePhysicalLocationTypeEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.utils.StringUtils;
import com.zzyl.vo.DeviceVo;
import com.zzyl.vo.ProductVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.lang.annotation.Repeatable;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DeviceServiceImpl implements DeviceService {

    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private Client client;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private DeviceMapper deviceMapper;

    /**
     * 同步产品列表
     */
    @Override
    public void syncProductList() {
        // 查询产品列表请求
        QueryProductListRequest request = new QueryProductListRequest();
        //假设每页200，将小型养老院的产品全部获取
        request.setPageSize(200);
        request.setCurrentPage(1);
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        QueryProductListResponse response;
        try {
            response = client.queryProductList(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        if (!response.getBody().success) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        List<ProductVo> collect = response
                .getBody()
                .getData()
                .getList()
                .getProductInfo()
                .stream().map(p -> BeanUtil.toBean(p, ProductVo.class))
                .collect(Collectors.toList());

        redisTemplate.opsForValue()
                .set(CacheConstants.All_PRODUCT_LIST,
                        JSONUtil.toJsonStr(collect));
    }

    /**
     * 注册设备
     * @param deviceDto
     */
    @Override
    public void registerDevice(DeviceDto deviceDto) {
        // 检查设备是否重复 根据设备名称
        Long count = deviceMapper.countByIotId(deviceDto.getDeviceName());
        // 判断设备是否重复 0 不重复 1 重复
        if (count > 0) {
            throw new BaseException(BasicEnum.IOT_DEVICE_REPEAT);
        }
        // 发送注册请求IOT新增设备
        RegisterDeviceRequest registerDeviceRequest = deviceDto.getRegisterDeviceRequest();
        // 设置实例ID
        registerDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        // 设置产品KEY 以便后面用到
        RegisterDeviceResponse response = null;
        try {
            response = client.registerDevice(registerDeviceRequest);
        } catch (Exception e) {
            // 注册失败
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        // 判断是否注册成功 非空判断
        if (response == null || !response.getBody().success) {
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        // 属性拷贝 获取注册成功后的设备信息
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        // 设置iotId,固定格式
        device.setIotId(response.getBody().getData().getIotId());

        //产品名称 根据产品key查询产品名称
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        // 设置实例ID
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        // 设置产品KEY
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        // 发送请求
        QueryProductResponse queryProductResponse;
        try {
            queryProductResponse = client.queryProduct(queryProductRequest);
        } catch (Exception e) {
            // 注册失败
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        //设置产品名称
        if (queryProductResponse.getBody().success) {
            device.setProductName(queryProductResponse.getBody().getData().productName);
        }

        // 判断是否是随身设备
        if (device.getLocationType().equals(DeviceLocationTypeEnum.PORTABLE_DEVICE.getOrdinal())) {
            // 设置为固定设备,如果不是随身设备那就是固定设备，并赋值
            device.setPhysicalLocationType(DevicePhysicalLocationTypeEnum.ELDER.getOrdinal());
        }


        try {
            deviceMapper.insertSelective(device);
            log.info("设备保存信息{}", device);
        } catch (Exception e) {
            // 删除ioc中的设备数据
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest();
            // 删除设备的名称
            deleteDeviceRequest.setDeviceName(deviceDto.getDeviceName());
            // 删除物联网设备ID
            deleteDeviceRequest.setIotId(device.getIotId());
            // 删除远程库里面的设备
            deleteDeviceRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
            // 删除产品KEY
            deleteDeviceRequest.setProductKey(deviceDto.getProductKey());

            try {
                // 删除设备
                client.deleteDevice(deleteDeviceRequest);
            } catch (Exception ex) {
                throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
            }
            throw new BaseException(BasicEnum.RE_SELECT_PRODUCT);

        }
    }

    /**
     * 查询产品列表
     * @return
     */
    @Override
    public List<ProductVo> allProduct() {
        String allProductList = redisTemplate
                .opsForValue()
                .get(CacheConstants.All_PRODUCT_LIST);
        if (StringUtils.isEmpty(allProductList)) {
            return Collections.emptyList();
        }

        return JSONUtil.toList(allProductList, ProductVo.class);
    }

    /**
     * 分页查询设备
     * @param pageNum
     * @param pageSize
     * @param deviceName
     * @param locationType
     * @param productKey
     * @return
     */
    @Override
    public PageResponse<DeviceVo> pageQueryDevice(Integer pageNum, Integer pageSize, String deviceName, Integer locationType, String productKey) {
        PageHelper.startPage(pageNum, pageSize);
        Page<DeviceVo> page = deviceMapper.pageQueryDevice(deviceName, locationType, productKey);
        return PageResponse.of(page, DeviceVo.class);
    }

    /**
     * 查询设备详情
     * @param request
     * @return
     */
    @Override
    public DeviceVo getDeviceDetail(QueryDeviceDetailRequest request) {

        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        QueryDeviceDetailResponse response;
        try {
            response = client.queryDeviceDetail(request);
        } catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if (!response.getBody().success) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        DeviceVo deviceDetail = deviceMapper.getDeviceDetail(response.getBody().getData().getIotId());
        QueryDeviceDetailResponseBody.QueryDeviceDetailResponseBodyData data = response.getBody().getData();
        BeanUtil.copyProperties(data, deviceDetail,CopyOptions.create().ignoreNullValue());
        return deviceDetail;
        
    }

    /**
     * 查询设备属性状态
     * @param request
     * @return
     */
    @Override
    public ResponseResult queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setIotId(request.getIotId());
        QueryDevicePropertyStatusResponse response;
        try {
            response = client.queryDevicePropertyStatus(request);
        }catch (Exception e) {
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if (!response.getBody().success){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }

        return ResponseResult.success(response.getBody().getData());
    }

    /**
     * 查询物模型
     * @param request
     * @return
     */
    @Override
    public ResponseResult queryThingModelPublished(QueryThingModelPublishedRequest request) {

        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        request.setProductKey(request.getProductKey());
        QueryThingModelPublishedResponse response;
        try {
            response = client.queryThingModelPublished(request);
        }catch (Exception e){
            throw new BaseException(BasicEnum.IOT_QUERY_THING_MODEL_PUBLISHED_ERROR);
        }
        return ResponseResult.success(response.getBody().getData());
    }

    @Override
    public void UpdateDevice(DeviceDto deviceDto) {
        //RegisterBatchUpdateDeviceNickname batchUpdateDeviceNickname = new RegisterBatchUpdateDeviceNickname();


    }
}
